using System.Net;
using Engine;
using Game;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
using System.Text;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Threading;
namespace StyleSurvivalcraft;

public class StyleUpdate
{
    public void Update()
    {
    }
    public static async Task ShowUpdate()
    {
        try
        {
            Program.Tasker();
            string title = "AI小贴士"; 
            string text = await Program.Tasker();
            DialogsManager.ShowDialog(null, new StyleDialog(title, text, delegate()
            {
                SettingsManager.BulletinTime = MotdManager.m_bulletin.Time;
            }));
    
            MotdManager.CanShowBulletin = false;
        }
        catch (Exception ex)
        {
            Log.Warning("ShowBulletin失败。原因: " + ex.Message);
        }
    }
    
    private static async Task<string> GetContentFromUrl(string url)
    {
        using (HttpClient client = new HttpClient())
        {
            try
            {
                string urlContent = await client.GetStringAsync(url);
                return urlContent;
            }
            catch (HttpRequestException e)
            {
                Log.Error($"Request error: {e.Message}");
                throw;
            }
            catch (Exception e)
            {
                Log.Error($"An error occurred: {e.Message}");
                throw;
            }
        }
    }
    class Program
    {
        static string newcr = ContentManager.Get<string>("AI", ".json");

        static string[] logLines = newcr.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                .Skip(1) // 跳过第一行
                .ToArray();
        static string x_appid = logLines[0].Trim();    // 第二行（实际索引0）
        static string api_secret = logLines[1].Trim(); // 第三行（实际索引1） 
        static string api_key = logLines[2].Trim();    // 第四行（实际索引2）

        static ClientWebSocket webSocket0;
        static CancellationToken cancellation;

        static string hostUrl = "https://spark-api.xf-yun.com/v1.1/chat";
        async public static Task<string> Tasker()
        {
            string question = "你是AI小贴士，给我一个小提示";
            string resp = "";
            string authUrl = GetAuthUrl();
            string url = authUrl.Replace("http://", "ws://").Replace("https://", "wss://");
            using (webSocket0 = new ClientWebSocket())
            {
                try
                {
                    await webSocket0.ConnectAsync(new Uri(url), cancellation);

                    JsonRequest request = new JsonRequest();
                    request.header = new Header()
                                    {
                                        app_id = x_appid,
                                        uid = "12345"
                                    };
                    request.parameter = new Parameter()
                                        {
                                            chat = new Chat()
                                            {
                                                domain = "lite",
                                                temperature = 0.5,
                                                max_tokens = 2048,
                                            }
                                        };
                    request.payload = new Payload()
                                        {
                                            message = new Message()
                                            {
                                                text = new List<Content>
                                                {
                                                    new Content() { role = "user", content = question },
                                                    // new Content() { role = "assistant", content = "....." }, // AI的历史回答结果，这里省略了具体内容，可以根据需要添加更多历史对话信息和最新问题的内容。
                                                }
                                            }
                                        };

                    var options = new JsonSerializerOptions 
                    { 
                        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                        WriteIndented = false
                    };
                    string jsonString = JsonSerializer.Serialize(request, options);
                    //连接成功，开始发送数据
                    

                    var frameData2 = System.Text.Encoding.UTF8.GetBytes(jsonString.ToString());

                    
                    webSocket0.SendAsync(new ArraySegment<byte>(frameData2), WebSocketMessageType.Text, true, cancellation);
                    
                    byte[] receiveBuffer = new byte[1024];
                    WebSocketReceiveResult result = await webSocket0.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), cancellation);
                    while (!result.CloseStatus.HasValue)
                    {
                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);
                           
                            using JsonDocument doc = JsonDocument.Parse(receivedMessage);
                            JsonElement root = doc.RootElement;
                            int code = root.GetProperty("header").GetProperty("code").GetInt32();
                            
                            
                            if(0==code){
                                int status = root
                                    .GetProperty("payload")
                                    .GetProperty("choices")
                                    .GetProperty("status")
                                    .GetInt32();

                                JsonElement textArray = root
                                    .GetProperty("payload")
                                    .GetProperty("choices")
                                    .GetProperty("text");
                                string content = textArray[0]
                                    .GetProperty("content")
                                    .GetString();
                                resp += content;

                                if(status != 2){
                                    Log.Information($"已接收到数据： {receivedMessage}");
                                }
                                else{
                                    Log.Information($"最后一帧： {receivedMessage}");
                                    int totalTokens = root
                                        .GetProperty("payload")
                                        .GetProperty("usage")
                                        .GetProperty("text")
                                        .GetProperty("total_tokens")
                                        .GetInt32();
                                    Log.Information($"整体返回结果： {resp}");
                                    Log.Information($"本次消耗token数： {totalTokens}");
                                    break;
                                }

                            }else{
                                Log.Information($"请求报错： {receivedMessage}");
                            }
                                

                        }
                        else if (result.MessageType == WebSocketMessageType.Close)
                        {
                            Log.Information("已关闭WebSocket连接");
                            break;
                        }

                        result = await webSocket0.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), cancellation);
                    }
                }
                catch (Exception e)
                {
                    Log.Information(e.Message);
                }
                finally
                {
                    if (webSocket0?.State == WebSocketState.Open)
                        await webSocket0.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
                }
            }
            return resp;
        }
        static string GetAuthUrl()
        {
            string date = DateTime.UtcNow.ToString("r");

            Uri uri = new Uri(hostUrl);
            StringBuilder builder = new StringBuilder("host: ").Append(uri.Host).Append("\n").//
                                    Append("date: ").Append(date).Append("\n").//
                                    Append("GET ").Append(uri.LocalPath).Append(" HTTP/1.1");

            string sha = HMACsha256(api_secret, builder.ToString());
            string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"", api_key, "hmac-sha256", "host date request-line", sha);

            string NewUrl = "https://" + uri.Host + uri.LocalPath;

            string path1 = "authorization" + "=" + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(authorization));
            date = date.Replace(" ", "%20").Replace(":", "%3A").Replace(",", "%2C");
            string path2 = "date" + "=" + date;
            string path3 = "host" + "=" + uri.Host;

            NewUrl = NewUrl + "?" + path1 + "&" + path2 + "&" + path3;
            return NewUrl;
        }




        public static string HMACsha256(string apiSecretIsKey, string buider)
        {
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(apiSecretIsKey);
            System.Security.Cryptography.HMACSHA256 hMACSHA256 = new System.Security.Cryptography.HMACSHA256(bytes);
            byte[] date = System.Text.Encoding.UTF8.GetBytes(buider);
            date = hMACSHA256.ComputeHash(date);
            hMACSHA256.Clear();

            return Convert.ToBase64String(date);

        }
    }
    public class JsonRequest
    {
        public Header header { get; set; }
        public Parameter parameter { get; set; }
        public Payload payload { get; set; }
    }

    public class Header
    {
        public string app_id { get; set; }
        public string uid { get; set; }
    }

    public class Parameter
    {
        public Chat chat { get; set; }
    }

    public class Chat
    {
        public string domain { get; set; }
        public double temperature { get; set; }
        public int max_tokens { get; set; }
    }

    public class Payload
    {
        public Message message { get; set; }
    }

    public class Message
    {
        public List<Content> text { get; set; }
    }

    public class Content
    {
        public string role { get; set; }
        public string content { get; set; }
    }
}
